﻿
using System;
using System.Reflection;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using DirectUI.Mobile.UI.Controls;
using DirectUI.Mobile.UI.Exception;
using DirectUI.Mobile.UI;
using DirectUI.Mobile.UI.Drawing.GdiPlus;
namespace DirectUI.Mobile.UI
{
    public class XPageParser : DirectUI.Mobile.UI.IParser
    {
        private readonly static  char[] indexDataBindingStartChar =new char[] { '{' };
        private readonly  static char[] indexDataBindingEndChar =new char[] { '}' };
        private string[] _commonEventName = { "Click", "ForeColorChanged", "Initialize", "KeyDown", "KeyPress", "KeyUp", "LostFocus", "PaintBackground", "ParentChanged", "SizeChanged", "VisibleChanged" };
        public XPageParser()
        {
        }

        public Page Parse(XmlNode node)
        {
            Page currentPage = ParseXPageTag(node);
            _currentPage = currentPage;
            XmlNode pageNode = null;
                 foreach (XmlNode n in node.ChildNodes)
            {
                if (n.Name == "DataSource")
                {
                    ParseDataSource(n);   

                }else if (n.Name == "Components")
                {
                    pageNode = n;
                }

            }
          
                    foreach (XmlNode tag in pageNode.ChildNodes)
                    {
                        DirectUIControl c = ParseNode(tag);
                        if (c != null)
                        {
                            currentPage.Add(c);
                        }
                    }
          
            return currentPage;
        }
        private void ParseObjectDataSource(XmlNode tag)
        {
            ObjectDataProvider provider = new ObjectDataProvider();
            provider.ObjectType = GetGlobalType(tag.Attributes["type"].Value);
            if (tag.Attributes["methodName"] != null)
            {
                provider.MethodName = tag.Attributes["methodName"].Value;
            }
            foreach (XmlNode n in tag.ChildNodes)
            {
                if (n.Name == "ConstructorParameter")
                {
                    foreach (XmlNode p in n.ChildNodes)
                    {
                        provider.ConstructorParameters.Add(ParseParameter(p));
                    }
                }
                else if (n.Name == "MethodParameter")
                {
                    foreach (XmlNode p in n.ChildNodes)
                    {
                        provider.MethodParameters.Add(ParseParameter(p));
                    }
                }

            }

            GlobeDataSourcePool.Instance.DataSourceCollection.Add(tag.Attributes["name"].Value, provider);
        }
        /// <summary>
        ///  <xs:element name="XmlDataProvider">
  ///  <xs:complexType>
  ///    <xs:sequence>
  ///   </xs:sequence>
  ///    <xs:attribute name="Source" type="xs:string"></xs:attribute>
  ///    <xs:attribute name="Name" type="xs:string"></xs:attribute>
  ///    <xs:attribute name="XPath" type="xs:string"></xs:attribute>
  ///  </xs:complexType>
  ///</xs:element>
        /// </summary>
        /// <param name="node"></param>
        private void ParseXmlDataSource(XmlNode node)
        {
            XmlDataProvider provider = new XmlDataProvider();
            if (node.Attributes["Source"] != null)
            {
                provider.Source = new Uri(node.Attributes["Source"].Value);
            }
            if (node.Attributes["XPath"] != null)
            {
                provider.XPath = node.Attributes["XPath"].Value;
            }
            GlobeDataSourcePool.Instance.DataSourceCollection.Add(node.Attributes["Name"].Value, provider);
        }
        private void ParseDataSource(XmlNode node)
        {


            foreach (XmlNode tag in node.ChildNodes)
            {
                if (tag.Name == "ObjectDataProvider")
                {
                    ParseObjectDataSource(tag);
                }
                if (tag.Name == "XmlDataProvider")
                {
                    ParseXmlDataSource(tag);
                }


            }
        }
        private object ParseParameter(XmlNode node)
        {
            string type = node.Attributes["type"].Value;
            string value = node.Attributes["value"].Value;
            Type t = Type.GetType(type);
            if (t==typeof(System.String))
            {
                return value;
            }
            else
            {
                
                if (t != null)
                {
                    MethodInfo minf = t.GetMethod("Parse", new Type[] { typeof(string) });
                  
                    object v = minf.Invoke(null, new object[] { value });
                    return v;
                }
                else
                {
                    throw new DirectUI.Mobile.UI.Exception.DataBinderException("Can't Not Find Type " + type);
                }
            }
        }
        private void SubscribeEvent(DirectUIControl c, string eventName, string handlerName)
        {
            Type t = c.GetType();
            //// Delegate.CreateDelegate(typeof(Handler),this,t.GetMethod("Hello")));
            //Delegate handler=Delegate
            MethodInfo method=_currentPage.GetType().GetMethod(handlerName);
            if (method == null)
            {
                throw new ParserException("Method " + handlerName + "Can not find");
            }
            EventHandler handler = delegate(object s, EventArgs e)
            {
                method.Invoke(_currentPage, new object[] { s, e });
            };
            t.GetEvent(eventName).AddEventHandler(c, handler);
             
        }
        private Page ParseXPageTag(XmlNode node)
        {
            Page currentPage = null;
            if (node.Attributes["class"] == null)
            {
                _className = "Page";
              currentPage= new Page();
              ParsePageAtrr(currentPage, node);
              return currentPage;
            }
            string className = node.Attributes["class"].Value;
            _className = className;
            if (node.Attributes["name"] == null)
            {
                throw new ParserException("必须指定Page的Name属性");
            }
            string pageName = node.Attributes["name"].Value;
            if (string.IsNullOrEmpty(className))
            {
                currentPage = new Page(pageName);
            }
            else
            {
                //currentPage =(Page) Activator.CreateInstance(Type.GetType(className));
                Type t = GetGlobalType(className);
                var ctor =t.GetConstructor(new Type[] { typeof(string) });
                if (ctor == null)
                {
                    currentPage =(Page) Activator.CreateInstance(t);
                    currentPage.Name = pageName;
                }
                else
                {
                    currentPage = (Page)ctor.Invoke(new object[] { pageName });
                }


            }
            if (currentPage != null)
            {
                ParsePageAtrr(currentPage, node);
            }
            return currentPage;
        }
        private string _className;
        private Page _currentPage;
        private Type GetGlobalType(string s) {
            string[] names = s.Split(new char[] { ',' });
            if (names.Length != 2)
            {
              ClassNameInvalidedException ex= new ClassNameInvalidedException();
              ex.ClassName = s;
              throw ex;
            }
            Assembly assem = Assembly.Load(names[1].Trim());
            if (assem == null)
            {
                ClassNameInvalidedException ex = new ClassNameInvalidedException("无法找到程序集"+names[1]);
                ex.ClassName = s;
             throw ex;

            }
           Type t= assem.GetType(names[0].Trim());
           if (t == null)
           {
                ClassNameInvalidedException ex = new ClassNameInvalidedException("无法加载类型 "+names[0]);
                ex.ClassName = s;
             throw ex;
           }
           return t;

        }
        private DirectUIControl ParseButton(XmlNode node)
        {
            DirectUIButton lb = new DirectUIButton();
            ParseCommonAtrr(lb, node);
            if (node.Attributes["content"] != null)
            {
                if (node.Attributes["content"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
                {
                    lb.Text = node.Attributes["content"].Value;
                }
                else
                {
                    ParseDataBind(lb, node.Attributes["content"].Value, "Text");
                }
            }
            if (node.Attributes["shadowColor"] != null)
            {
                lb.ShadowColor = ColorConverter.FromString(node.Attributes["shadowColor"].Value);
            }
            if (node.Attributes["Command"] != null)
            {
                lb.Command = node.Attributes["Command"].Value;
            }
            if (node.Attributes["pressedBackColor"] != null)
            {
                lb.PressedBackColor = ColorConverter.FromString(node.Attributes["pressedBackColor"].Value);
            }
            if (node.Attributes["pressedForeColor"] != null)
            {
                lb.PressedForeColor = ColorConverter.FromString(node.Attributes["pressedForeColor"].Value);
            }
            ////Will Change Later
            //if (lb.BackColor == Color.Transparent)
            //{
            //    lb.ShadowColor = Color.Gray;
            //    //     lb.Font = new Font(FontFamily.GenericMonospace,10, FontStyle.Bold);
            //}
            return lb;
        }
        private DirectUIControl ParsePictureBox(XmlNode node)
        {
            throw new NotImplementedException();
            //DirectUIPictureBox lb = new DirectUIPictureBox();
            //ParseCommonAtrr(lb, node);

            //if (node.Attributes["src"] != null)
            //{
            //    if (node.Attributes["src"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
            //    {
            //        lb.Src = node.Attributes["src"].Value;
            //        //string[] fileNames = node.Attributes["src"].Value.Split(':');
            //        //if (fileNames.Length != 2)
            //        //{
            //        //    throw new ParserException("Picture Box " + lb.Name + "'s Image src is invalide");
            //        //}
            //        //lb.Image = DirectUI.Common.ResourceManagerProxy.GetImage(DirectUI.Common.Util.GetAppPath() + "\\" + fileNames[0], fileNames[1]);
            //    }
            //    else
            //    {
            //        ParseDataBind(lb, node.Attributes["src"].Value, "Src");

            //    }

            //}
            ////Will Change Later
            ////if (lb.BackColor == Color.Transparent)
            ////{
            ////    lb.ShadowColor = Color.Gray;
            ////    //     lb.Font = new Font(FontFamily.GenericMonospace,10, FontStyle.Bold);
            ////}
            //return lb;
        }
        private DirectUIControl ParseLabel(XmlNode node)
        {
            DirectUILabel lb = new DirectUILabel();
            ParseCommonAtrr(lb, node);
            if (node.Attributes["content"] != null)
            {
                if (node.Attributes["content"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
                {
                    lb.Text = node.Attributes["content"].Value;
                }
                else
                {
                    ParseDataBind(lb, node.Attributes["content"].Value, "Text");
                }
            }
            if (node.Attributes["shadowColor"] != null)
            {
                lb.ShadowColor = ColorConverter.FromString(node.Attributes["shadowColor"].Value);
            }
            //Will Change Later
            //if (lb.BackColor == Color.Transparent)
            //{
            //    lb.ShadowColor = Color.Gray;
            //    //     lb.Font = new Font(FontFamily.GenericMonospace,10, FontStyle.Bold);
            //}
            return lb;
        }
        private DirectUIControl ParseCheckBox(XmlNode node)
        {
            DirectUICheckBox cb = new DirectUICheckBox();
            ParseCommonAtrr(cb, node);
            if (node.Attributes["IfChecked"] != null)
            {
                if (node.Attributes["IfChecked"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
                {
                    cb.IfChecked = bool.Parse(node.Attributes["IfChecked"].Value);
                }
                else
                {
                    ParseDataBind(cb, node.Attributes["IfChecked"].Value, "IfChecked");
                }
            }
            if (node.Attributes["OnChecked"] != null)
            {
                SubscribeEvent(cb, "Checked", node.Attributes["OnChecked"].Value);
            }
            if (node.Attributes["OnUnChecked"] != null)
            {
                SubscribeEvent(cb, "UnChecked", node.Attributes["OnUnChecked"].Value);
            }
           
            //Will Change Later
            //if (lb.BackColor == Color.Transparent)
            //{
            //    lb.ShadowColor = Color.Gray;
            //    //     lb.Font = new Font(FontFamily.GenericMonospace,10, FontStyle.Bold);
            //}
            return cb;
        }
        private FontStyle getFontStyleFromString(string name)
        {
            name = name.ToLower();
            switch (name)
            {
                case "regular":
                    return FontStyle.Regular;
                case"italic":
                   return  FontStyle.Italic;
                case "strikeout":
                    return FontStyle.Strikeout;
                case "underline" :
                    return FontStyle.Underline;
                case "bold":
                    return FontStyle.Bold;
                default:
                    return FontStyle.Regular;
            }
        }
        private void ParsePageAtrr(Page c, XmlNode node)
        {
            if (node.Attributes["name"] != null)
            {
                c.Name = node.Attributes["name"].Value;
            }
            if (node.Attributes["prev"] != null)
            {
                c.PrevPage = node.Attributes["prev"].Value;
            }
            if (node.Attributes["next"] != null)
            {
                c.NextPage= node.Attributes["next"].Value;
            }
            if (node.Attributes["backColor"] == null)
            {
                c.BackColor = Color.Transparent;
            }
            else
            {
                c.BackColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["backColor"].Value);
            }
            if (node.Attributes["foreColor"] == null)
            {
                c.ForeColor = Color.Black;
            }
            else
            {
                c.ForeColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["foreColor"].Value);
            }
            for (int i = 0; i < _commonEventName.Length; i++)
            {
                if (node.Attributes["On" + _commonEventName[i]] != null)
                {
                    SubscribeEvent(c, _commonEventName[i], node.Attributes["On" + _commonEventName[i]].Value);
                }
            }
        }
        private void ParseCommonAtrr(DirectUIControl c, XmlNode node)
        {
       
            c.Bounds = GetBounds(node);
            if (node.Attributes["name"] != null)
            {
                c.Name = node.Attributes["name"].Value;
            }
            else
            {
                c.Name = Guid.NewGuid().ToString();
            }
     
            if (node.Attributes["backColor"] == null)
            {
                c.BackColor = Color.Transparent;            
            }
            else
            {
                c.BackColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["backColor"].Value);
            }
            //visible
            if (node.Attributes["visible"] != null)
            {
                c.Visible =bool.Parse( node.Attributes["visible"].Value);
            }
            else
            {
                c.Visible = true;
            }
            if (node.Attributes["foreColor"] == null)
            {
                c.ForeColor = Color.Black;
            }
            else
            {
                c.ForeColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["foreColor"].Value);
            }
            FontStyle fontStyle = FontStyle.Regular;
            float fontSize = 10f;
            if (node.Attributes["fontStyle"] != null)
            {
            //    Font font=new Font(FontFamily.GenericMonospace,12,fon
                fontStyle = getFontStyleFromString(node.Attributes["fontStyle"].Value);
            }
            if (node.Attributes["fontSize"] != null)
            {
                fontSize = float.Parse(node.Attributes["fontSize"].Value);
            }
            c.Font = new Font(FontFamily.GenericSansSerif, fontSize, fontStyle);
            for (int i = 0; i < _commonEventName.Length; i++)
            {
                if (node.Attributes["On" + _commonEventName[i]] != null)
                {
                    SubscribeEvent(c, _commonEventName[i], node.Attributes["On" + _commonEventName[i]].Value);
                }
            }
        }
        private DirectUIControl ParseAutoComplete(XmlNode node)
        {
            AutoComplete ac = new AutoComplete();
            ParseCommonAtrr(ac, node);
            if (node.Attributes["content"] != null)
            {
                if (node.Attributes["content"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
                {
                    ac.Text = node.Attributes["content"].Value;
                }
                else
                {
                    ParseDataBind(ac, node.Attributes["content"].Value, "Text");
                }
            }
            if (node.Attributes["OnTextChanged"] != null)
            {
                SubscribeEvent(ac, "TextChanged", node.Attributes["OnTextChanged"].Value);
            }
         //  ac.ServiceMethod=new AutoComplete.AutoCompleteServiceMethod(
            MethodInfo method = _currentPage.GetType().GetMethod(node.Attributes["serviceMethod"].Value);
            AutoComplete.AutoCompleteServiceMethod handler = delegate(string s)
            {
               return  (IList<string>)method.Invoke(_currentPage, new object[] { s });
            };
            ac.ServiceMethod = handler;
            return ac;

        }
        private DirectUIControl ParseEdit(XmlNode node)
        {
            DirectUITextBox tb = new DirectUITextBox();
            ParseCommonAtrr(tb, node);
            if (node.Attributes["content"] != null)
            {
                if (node.Attributes["content"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
                {
                    tb.Text = node.Attributes["content"].Value;
                }
                else
                {
                    ParseDataBind(tb, node.Attributes["content"].Value, "Text");
                }
            }
            if (node.Attributes["OnTextChanged"] != null)
            {
                SubscribeEvent(tb, "TextChanged", node.Attributes["OnTextChanged"].Value);
            }
                
            if (node.Attributes["validRegularString"] != null)
            {
                tb.ValidRegularString = node.Attributes["validRegularString"].Value;
            }
            return tb;
        }
        private void ParseDataBind(DirectUIControl c, string bindingString,string propertyName)
        {
            try
            {
                int start = bindingString.IndexOfAny(indexDataBindingStartChar);
                int end = bindingString.LastIndexOfAny(indexDataBindingEndChar);

                string[] bindingContent = bindingString.Substring(start + 1, end - start - 1).Split(new char[] { ',' });
              // For ListBox ,I Will Change this Later
                if (bindingContent.Length == 1 && (bindingContent[0].IndexOf("Path=") != -1 | bindingContent[0].IndexOf("XPath=") != -1))
                {
                     DataBinding bind = new DataBinding();
                        bind.Mode = BindingMode.TwoWay;         
                         //   bind.DataSource = ((DataSourceProvider)dataSource).Data;
                       //     bind.DataSource = ((DataSourceProvider)dataSource);            
                            int pathIndex = bindingContent[0].IndexOf("XPath=");

                            if (pathIndex != -1)
                            {
                                bind.XPath = bindingContent[0].Substring(pathIndex + 6);

                                //  bind.Path = new PropertyPath("Data."+bindingContent[1].Substring(pathIndex + 5));
                            }
                            else
                            {
                                pathIndex = bindingContent[0].IndexOf("Path=");
                                if (pathIndex != -1)
                                {
                                    bind.Path = new PropertyPath(bindingContent[0].Substring(pathIndex + 5));

                                    //  bind.Path = new PropertyPath("Data."+bindingContent[1].Substring(pathIndex + 5));
                                }
                                else
                                {
                                    throw new Exception.ParserException("Control " + c.Name + " dataBinding string  " + propertyName + "=" + bindingString + "   is Invalidate");
                                }
                            }
                            c.SetBinding(propertyName, bind);
                            return;
                }
                int bcStart = bindingContent[0].IndexOfAny(indexDataBindingStartChar) + 1;
                int bcEnd = bindingContent[0].IndexOfAny(indexDataBindingEndChar);
                string[] bindingSource = bindingContent[0].Substring(bcStart, bcEnd - bcStart).Split(null);
                if (bindingSource[0] == "ObjectDataProvider")
                {
                    string sourceName = bindingSource[bindingSource.Length - 1];
                    if( GlobeDataSourcePool.Instance.DataSourceCollection.ContainsKey(sourceName))
                    {
                        object dataSource =GlobeDataSourcePool.Instance.DataSourceCollection[sourceName];
                        DataBinding bind = new DataBinding();
                        bind.Mode = BindingMode.TwoWay;
                        if (bindingContent.Length > 1)
                        {
                            //   bind.DataSource = ((DataSourceProvider)dataSource).Data;
                            //     bind.DataSource = ((DataSourceProvider)dataSource);
                            bind.DataSourceName = sourceName;
                            int pathIndex = bindingContent[1].IndexOf("Path=");
                            if (pathIndex != -1)
                            {
                                //  bind.Path = new PropertyPath("Data."+bindingContent[1].Substring(pathIndex + 5));
                                bind.Path = new PropertyPath(bindingContent[1].Substring(pathIndex + 5));

                            }
                            else
                            {
                                throw new Exception.ParserException("Control " + c.Name + " dataBinding string  " + propertyName + "=" + bindingString + "   is Invalidate");
                            }
                        }
                        else
                        {
                            bind.DataSource = dataSource;
                            //  bind.DataSourceName = sourceName;
                            bind.Mode = BindingMode.TwoWay;
                            // bind.Path = new PropertyPath("Data");
                        }

                        c.SetBinding(propertyName, bind);
                    }
                    else
                    {
                        throw new Exception.ParserException("Control " + c.Name + " dataBinding string  " + propertyName + "=" + bindingString + "   is Invalidate");

                    }
                }
                else if (bindingSource[0] == "XmlDataProvider")
                {
                    string sourceName = bindingSource[bindingSource.Length - 1];
                    if (GlobeDataSourcePool.Instance.DataSourceCollection.ContainsKey(sourceName))
                    {
                        object dataSource = GlobeDataSourcePool.Instance.DataSourceCollection[sourceName];
                        DataBinding bind = new DataBinding();
                        bind.Mode = BindingMode.TwoWay;
                        if (bindingContent.Length > 1)
                        {
                            //   bind.DataSource = ((DataSourceProvider)dataSource).Data;
                            //     bind.DataSource = ((DataSourceProvider)dataSource);
                            bind.DataSourceName = sourceName;
                            int pathIndex = bindingContent[1].IndexOf("XPath=");
                            if (pathIndex != -1)
                            {
                                //  bind.Path = new PropertyPath("Data."+bindingContent[1].Substring(pathIndex + 5));
                                bind.XPath =bindingContent[1].Substring(pathIndex + 6);

                            }
                            else
                            {
                                throw new Exception.ParserException("Control " + c.Name + " dataBinding string  " + propertyName + "=" + bindingString + "   is Invalidate");
                            }
                        }
                        else
                        {
                            bind.DataSource = dataSource;
                            //  bind.DataSourceName = sourceName;
                            bind.Mode = BindingMode.TwoWay;
                            // bind.Path = new PropertyPath("Data");
                        }

                        c.SetBinding(propertyName, bind);
                    }
                    else
                    {
                        throw new Exception.ParserException("Control " + c.Name + " dataBinding string  " + propertyName + "=" + bindingString + "   is Invalidate");

                    }
                
                }
            }
            catch (System.Exception ex)
            {
                throw new Exception.ParserException("Control " + c.Name + " dataBinding string  " + propertyName + "=" + bindingString + "   is Invalidate",ex);

            }
        }
        private DirectUIControl ParseComboBox(XmlNode node)
        {
            DirectUIComboBox cb = new DirectUIComboBox();
            ParseCommonAtrr(cb, node);
            if(node.Attributes["OnSelectedIndexChanged"]!=null){
                SubscribeEvent(cb, "SelectedIndexChanged", node.Attributes["OnSelectedIndexChanged"].Value);
            }
           
            if (node.Attributes["items"] != null)
            {

                if (node.Attributes["dataTextField"] == null || node.Attributes["dataValueField"] == null)
                {
                    throw new Exception.ParserException(" if DirectUIComboBox 's items property is seted, dataTextField and dataValueField must to be  setted");
                }
                cb.DataTextField = node.Attributes["dataTextField"].Value;
                cb.DataValueField = node.Attributes["dataValueField"].Value;
                ParseDataBind(cb, node.Attributes["items"].Value, "Items");
            }
            foreach (XmlNode n in node.ChildNodes)
            {
                if (n.Name == "Combo")
                {
                    DirectUIComboBoxItem item = new DirectUIComboBoxItem();
                    item.Text = n.Attributes["content"].Value;
                    item.Value =n.Attributes["value"].Value;
                    cb.Items.Add(item);
                }
            }
            if (node.Attributes["selectedValue"] != null)
            {
                if (node.Attributes["selectedValue"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
                {
                    cb.SelectedValue = node.Attributes["selectedValue"].Value;
                }
                else
                {
                    ParseDataBind(cb, node.Attributes["selectedValue"].Value, "SelectedValue");
                }
            }
            if (node.Attributes["borderColor"] != null)
            {
                cb.BorderColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["borderColor"].Value);        
            }
            if (node.Attributes["selectedText"] != null)
            {
                if (node.Attributes["selectedText"].Value.IndexOfAny(indexDataBindingStartChar) == -1)
                {
                    cb.SelectedText = node.Attributes["selectedText"].Value;
                }
                else
                {
                    ParseDataBind(cb, node.Attributes["selectedText"].Value, "SelectedText");
                }
            }
            //绑定默认的数据
            if (cb.SelectedItemIndex == 0&&cb.Items.Count>=1)
            {
                cb.SelectedItemIndex = 0;
            }
            return cb;

        }
        //Layer Engine
        private Rectangle GetBounds(XmlNode node)
        {
            Rectangle bounds = new Rectangle(int.Parse(node.Attributes["x"].Value), int.Parse(node.Attributes["y"].Value), int.Parse(node.Attributes["w"].Value), int.Parse(node.Attributes["h"].Value));
            return bounds;
        }
        private DirectUIControl ParseDataTemplate(XmlNode node)
        {
            DirectUITemplate tp = new DirectUITemplate();
            if (node.Attributes["name"] != null)
            {
                tp.Name = node.Attributes["name"].Value;
            }
            else
            {
                tp.Name = Guid.NewGuid().ToString();
            }
            foreach (XmlNode n in node.ChildNodes)
            {
                DirectUIControl c = ParseNode(n);
                tp.Controls.Add(c);
            }
            return tp;
        }
        private DirectUIControl ParseListBox(XmlNode node)
        {
            DirectUIListBox lb = new DirectUIListBox();
            ParseCommonAtrr(lb, node);
            if (node.Attributes["ItemHeight"] != null)
            {
                lb.ItemHeight = int.Parse(node.Attributes["ItemHeight"].Value);
            }
            if (node.Attributes["Alpha"] != null)
            {
                lb.Alpha = int.Parse(node.Attributes["Alpha"].Value);
            }
            if (node.Attributes["DataSource"] != null)
            {

             //   lb.DataSource = PageManager.Instance.DataSourceCollection[node.Attributes["DataSource"].ToString()];
                ParseDataBind(lb, node.Attributes["DataSource"].Value, "DataSource");
            }
            if (node.Attributes["OnCommand"] != null)
            {
                SubscribeEvent(lb, "Command", node.Attributes["OnCommand"].Value);
                       
            }
            if (node.Attributes["OnDataSourceChanged"] != null)
            {
                SubscribeEvent(lb, "DataSourceChanged", node.Attributes["OnDataSourceChanged"].Value);

            }
            //
            if (node.Attributes["ItemTemplate"] != null)
            {

                lb.ItemTemplate =(DirectUITemplate) _currentPage.FindControl(node.Attributes["ItemTemplate"].Value);
                _currentPage.Controls.Remove(lb.ItemTemplate);
            }
            if (node.Attributes["SelectedBackColor"] != null)
            {
                lb.SelectedBackColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["SelectedBackColor"].Value);
            }
            if (node.Attributes["SelectedForeColor"] != null)
            {
                lb.SelectedForeColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["SelectedForeColor"].Value);
            }
            if (node.Attributes["PressedBackColor"] != null)
            {
                lb.PressedBackColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["PressedBackColor"].Value);
            }
            if (node.Attributes["PressedForeColor"] != null)
            {
                lb.PressedForeColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["PressedForeColor"].Value);
            }
            if (node.Attributes["HoveredBackColor"] != null)
            {
                lb.HoveredBackColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["HoveredBackColor"].Value);
            }
            if (node.Attributes["HoveredForeColor"] != null)
            {
                lb.HoveredForeColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["HoveredForeColor"].Value);
            }
            if (node.Attributes["BorderColor"] != null)
            {
                lb.BorderColor = DirectUI.Mobile.UI.Drawing.GdiPlus.ColorConverter.FromString(node.Attributes["BorderColor"].Value);
            }
            return lb;
            
        }
        private DirectUIControl ParsePanel(XmlNode node)
        {
            DirectUIPanel pl = new DirectUIPanel();
            ParseCommonAtrr(pl, node);
           
            if (node.Attributes["GradientFill"] != null)
            {
                bool gf = bool.Parse(node.Attributes["GradientFill"].Value);
                pl.GradientFill = gf;
            
            }
            if (node.Attributes["GradientFillOffset"] != null)
            {
                pl.GradientFillOffset = int.Parse(node.Attributes["GradientFillOffset"].Value);
            }
            if (node.Attributes["Alpha"] != null)
            {
                pl.Alpha = int.Parse(node.Attributes["Alpha"].Value);
                pl.EnableDoubleBuffer = true;
            }
            foreach (XmlNode n in node.ChildNodes)
            {
                DirectUIControl c = ParseNode(n);
                if (c != null)
                {
                    pl.Controls.Add(c);
                }
            }
            return pl;
        }
        private DirectUIControl ParseNode(XmlNode node)
        {
            DirectUIControl c = null;
            switch (node.Name)
            {
                case "Label":
                    c = ParseLabel(node);
                    break;
                case "Edit":
                    c = ParseEdit(node);
                    break;
                case "Button":
                    c = ParseButton(node);
                    break;
                case "ComboBox":
                    c = ParseComboBox(node);
                    break;
                case "AutoComplete":
                    c = ParseAutoComplete(node);
                    break;
                case"Panel":
                    c = ParsePanel(node);
                    break;
                case"DataTemplate":
                    c = ParseDataTemplate(node);
                    break;
                case"ListBox":
                    c = ParseListBox(node);
                    break;
                case"CheckBox":
                    c = ParseCheckBox(node);
                    break;
                case"PictureBox":
                    c = ParsePictureBox(node);
                    break;
            }

            return c;
        }
    }
}
